package org.dev.hi.hiui.title

import android.content.Context
import android.graphics.Typeface
import android.text.TextUtils
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.annotation.StringRes
import org.dev.hi.hiui.R
import org.dev.hi.hiui.iconFont.IconFontButton
import org.dev.hi.hiui.iconFont.IconFontTextView
import org.dev.hi.library.util.HiRes
import java.lang.IllegalStateException

/**
 * Author WenPing
 * CreateTime 2021/8/22.
 * Description:自定义导航栏
 */
class HiNavigationBar @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defstyle: Int = 0
) : RelativeLayout(context, attributeSet, defstyle) {
    // 主副标题
    private var titleView: IconFontTextView? = null
    private var subTitleView: IconFontTextView? = null
    private var titleContainer: LinearLayout? = null

    // 左右按钮
    private var mLeftLastViewId = View.NO_ID
    private var mRightLastViewId = View.NO_ID
    private var mLeftViewList: ArrayList<View> = ArrayList<View>()
    private var mRightViewList: ArrayList<View> = ArrayList<View>()

    // 解析属性获得Attrs对象
    private var navAttrs = AttrsParse
        .parseAttrs(context, attributeSet, defstyle)

    init {
        // 设置标题
        if (!TextUtils.isEmpty(navAttrs.navTitle)) {
            setTitle(navAttrs.navTitle!!)
        }
        // 设置副标题
        if (!TextUtils.isEmpty(navAttrs.navSubtitle)) {
            setSubTitle(navAttrs.navSubtitle!!)
        }
        // 设置line
        if (navAttrs.lineHeight > 0) {
            addLineView()
        }
    }

    /**
     * 暴露给使用方
     */
    fun setNavListener(listener: OnClickListener) {
        if (TextUtils.isEmpty(navAttrs.navIconStr))
            return
        val navBackView = addLeftTextButton(
            navAttrs.navIconStr!!,
            R.id.id_nav_left_back_view
        )
        navBackView.setTextSize(
            TypedValue.COMPLEX_UNIT_PX,
            navAttrs.navIconSize
        )
        navBackView.setTextColor(navAttrs.navIconColor)
        navBackView.setOnClickListener(listener)

    }

    fun addLeftTextButton(@StringRes stringRes: Int, viewId: Int): Button {
        return addLeftTextButton(HiRes.getString(stringRes), viewId)
    }

    /**
     * 添加左侧按钮 back键等；暴露给使用方
     */
    fun addLeftTextButton(buttonText: String, viewId: Int): Button {
        val button = generateTextButton()
        button.text = buttonText
        button.id = viewId
        if (mLeftViewList.isEmpty()) {
            button.setPadding(navAttrs.horPadding * 2, 0, navAttrs.horPadding, 0)
        } else {
            button.setPadding(navAttrs.horPadding, 0, navAttrs.horPadding, 0)
        }

        addLeftView(button, generateTextButtonLayoutParams())
        return button
    }


    /**
     * 添加左侧控件
     */
    private fun addLeftView(
        view: View,
        params: LayoutParams
    ) {
        val viewId = view.id
        // 如果 viewId 为 View.NO_ID，需要抛出异常
        if (viewId == View.NO_ID) {
            throw IllegalStateException("left view must has an unique id.")
        }
        /**
         * mLeftLastButtonId 为空表示第一次添加
         * mLeftLastButtonId 不为空，则调用该方法addButton需要在前面按钮的右边摆放
         */
        if (mLeftLastViewId == View.NO_ID) {
            params.addRule(ALIGN_PARENT_LEFT, viewId)
        } else {
            params.addRule(RIGHT_OF, mLeftLastViewId)
        }
        // 给mLeftLastButtonId 设置id
        mLeftLastViewId = viewId
        /**
         * alignWithParent 表示 如果锚点不存在或者锚点的不可见，则使用父级做为锚点
         */
        params.alignWithParent = true
        mLeftViewList.add(view)
        addView(view, params)
    }


    fun addRightTextButton(@StringRes stringRes: Int, viewId: Int): Button {
        return addRightTextButton(HiRes.getString(stringRes), viewId)
    }

    fun addRightTextButton(buttonText: String, viewId: Int): Button {
        val button = generateTextButton()
        button.text = buttonText
        button.id = viewId
        if (mRightViewList.isEmpty()) {
            button.setPadding(navAttrs.horPadding, 0, navAttrs.horPadding * 2, 0)
        } else {
            button.setPadding(navAttrs.horPadding, 0, navAttrs.horPadding, 0)
        }

        addRightView(button, generateTextButtonLayoutParams())
        return button
    }

    fun addRightView(
        view: View,
        params: LayoutParams
    ) {
        val viewId = view.id
        if (viewId == View.NO_ID) {
            throw IllegalStateException("right view must has an unique id.")
        }
        if (mRightLastViewId == View.NO_ID) {
            params.addRule(ALIGN_PARENT_RIGHT, viewId)
        } else {
            params.addRule(LEFT_OF, mRightLastViewId)
        }
        mRightLastViewId = viewId
        params.alignWithParent = true  //alignParentIfMissing
        mRightViewList.add(view)
        addView(view, params)
    }

    /**
     * 给导航栏添加底部的线条
     */
    private fun addLineView() {
        val view = View(context)
        val params = LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            navAttrs.lineHeight
        )
        // 设置显示在底部
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
        view?.apply {
            layoutParams = params
            setBackgroundColor(navAttrs.lineColor)
        }
        addView(view)
    }

    fun setTitle(navTitle: String) {
        ensureTitleView()
        titleView?.text = navTitle
        titleView?.visibility =
            if (TextUtils.isEmpty(navTitle)) GONE
            else VISIBLE
    }

    private fun setSubTitle(navSubtitle: String) {
        ensureSubtitleView()
        updateTitleViewStyle()
        subTitleView?.text = navSubtitle
        subTitleView?.visibility = if (TextUtils.isEmpty(navSubtitle)) GONE
        else VISIBLE
    }
    // 配合HiSearchView使用
    fun setCenterView(view: View) {
        var params = view.layoutParams
        if (params == null) {
            // 不是相对布局的params不能直接用
            params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
        } else if (params !is LayoutParams) {
            params = LayoutParams(params)
        }

        val centerViewParams = params as LayoutParams
        centerViewParams.addRule(RIGHT_OF, mLeftLastViewId)
        centerViewParams.addRule(LEFT_OF, mRightLastViewId)
        params.addRule(CENTER_VERTICAL)
        addView(view, centerViewParams)
    }

    /**
     * 计算导航栏 内部控件显示
     */
    private fun generateTextButtonLayoutParams(): LayoutParams {
        return LayoutParams(
            LayoutParams.WRAP_CONTENT,
            LayoutParams.MATCH_PARENT
        )
    }

    /**
     * 生成 按钮
     */
    private fun generateTextButton(): Button {
        val button = IconFontButton(context)
        // setBackgroundResource(0) 不设置背景
        button.setBackgroundResource(0)
        button.minWidth = 0
        button.minimumWidth = 0
        button.minHeight = 0
        button.minimumHeight = 0
        button.setTextSize(TypedValue.COMPLEX_UNIT_PX, navAttrs.btnTextSize)
        button.setTextColor(navAttrs.btnTextColor)
        button.gravity = Gravity.CENTER
        // includeFontPadding 设置 TextView 是否包含额外的顶部和底部填充，默认为true；
        button.includeFontPadding = false
        return button
    }


    /**
     * 设置副标题的显示样式
     */
    private fun ensureSubtitleView() {
        if (subTitleView == null) {
            subTitleView = IconFontTextView(context, null)
            subTitleView?.apply {
                gravity = Gravity.CENTER
                isSingleLine = true
                ellipsize = TextUtils.TruncateAt.END
                setTextColor(navAttrs.subTitleTextColor)
                textSize = navAttrs.subTitleSize

                // 添加到标题容器中
                ensureTitleContainer()
                titleContainer?.addView(subTitleView)
            }
        }
    }


    private fun ensureTitleView() {
        if (titleView == null) {
            titleView = IconFontTextView(
                context,
                null
            )
            // 设置
            titleView?.apply {
                gravity = Gravity.CENTER
                isSingleLine = true
                ellipsize = TextUtils.TruncateAt.END
                setTextColor(navAttrs.titleTextColor)
                // 调整标题在导航栏中的显示样式
                updateTitleViewStyle()
                ensureTitleContainer()
                // 标题容器添加标题，放在第一个序号
                titleContainer?.addView(titleView, 0)

            }
        }
    }

    /**
     * 设置标题容器在导航栏中的显示尺寸参数
     */
    private fun ensureTitleContainer() {
        if (titleContainer == null) {
            titleContainer = LinearLayout(context)
            titleContainer?.apply {
                orientation = LinearLayout.HORIZONTAL
                gravity = Gravity.CENTER
                // 这里用相对布局的params，设置标题容器在导航栏中的显示效果
                val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
                params.addRule(CENTER_IN_PARENT)
                this@HiNavigationBar.addView(titleContainer, params)
            }
        }
    }

    /**
     * 判断副标题是否存在，调整主标题显示样式
     */
    private fun updateTitleViewStyle() {
        if (titleView == null)
            return
        // 副标题不存在|| 副标题的文字为空
        if (subTitleView == null || TextUtils.isEmpty(subTitleView!!.text)) {
            titleView?.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                navAttrs.titleTextSize
            )
            // 设置文字加重显示
            titleView?.typeface = Typeface.DEFAULT_BOLD
        } else {
            titleView?.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                navAttrs.titleTextSizeWithSubTitle
            )
            // 显示显示样式为默认
            titleView?.typeface = Typeface.DEFAULT

        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        if (titleContainer != null) {
            // 计算出标题左侧已占用的空间
            var leftUseSpace = paddingLeft
            for (view in mLeftViewList) {
                leftUseSpace += view.measuredWidth
            }
            // 计算右侧标题占用的空间
            var rightUseSpace = paddingRight
            for (view in mRightViewList) {
                rightUseSpace += view.measuredWidth
            }
            val titleContainerWidth = titleContainer!!.measuredWidth
            // 为了让标题居中，取两侧边距的大值
            val remainingSpace = measuredWidth - Math.max(leftUseSpace, rightUseSpace)
            if (remainingSpace < titleContainerWidth) {
                val size = MeasureSpec.makeMeasureSpec(remainingSpace, MeasureSpec.EXACTLY)
                titleContainer!!.measure(size, heightMeasureSpec)
            }
        }
    }

}